package com.example.exjnidemo.exbluetooth01.m;


import android.bluetooth.BluetoothAdapter;
        import android.bluetooth.BluetoothDevice;
        import android.content.BroadcastReceiver;
        import android.content.Context;
        import android.content.IntentFilter;
        import android.util.Log;

        import com.example.exjnidemo.exbluetooth01.LogUtil;
        import com.example.exjnidemo.exbluetooth01.b.ScanBluetoothReceiver;
        import com.example.exjnidemo.exbluetooth01.i.ScanBluetoothListener;

        import java.io.IOException;
        import java.lang.reflect.InvocationTargetException;
        import java.lang.reflect.Method;
        import java.util.Set;
        import java.util.UUID;

/**
 *  表示本地设备蓝牙适配器
 *  BluetoothAdapter允许您执行基本的蓝牙任务,如启动设备发现,查询一个保税(配对)设备列表,
 *  实例化一个BluetoothDevice使用一个已知的MAC地址,
 *  并创建一个BluetoothServerSocket从其他设备监听连接请求,并开始一个扫描蓝牙设备。
 *
 *
 *  要获得一个代表本地蓝牙适配器的BluetoothAdapter，
 *  调用BluetoothManager上的BluetoothManager#getAdapter函数。
 *  在JELLY_BEAN_MR1及以下，您将需要使用静态的getDefaultAdapter()方法。
 *
 *
 *  从根本上说，这是所有蓝牙操作的起点。
 *  一旦你有了本地适配器，你可以通过getBondedDevices()获得一组代表所有配对设备的BluetoothDevice对象;
 *  使用startDiscovery()启动设备发现;
 *  或者使用 listenUsingRfcommWithServiceRecord(java.lang. lang. lang)
 *  创建一个BluetoothServerSocket来监听传入的RFComm连接请求。
 *  字符串,java.util.UUID);
 *  使用listenUsingL2capChannel()监听传入的L2CAP连接导向通道(CoC)连接请求;
 *  或者使用startLeScan(android.bluetooth.BluetoothAdapter.LeScanCallback)启动蓝牙LE设备扫描。
 *
 *
 * //        BluetoothDevice;
 * //        BluetoothServerSocket;
 */

public class YXJBluetoothManager {

    private static YXJBluetoothManager manager ;

    private BluetoothAdapter adapter;
    private ScanBluetoothReceiver scanBluetoothReceiver ;

    private ScanBluetoothListener scanBluetoothListener;

    public void setScanBluetoothListener(ScanBluetoothListener scanBluetoothListener) {
        this.scanBluetoothListener = scanBluetoothListener;
    }


    private YXJBluetoothManager(){
        /*获取蓝牙适配器实例*/
        adapter = BluetoothAdapter.getDefaultAdapter();
        LogUtil.v("isSupportBluetooth="+isSupportBluetooth());
        LogUtil.v("isBlueEnable="+isBlueEnable());
    }



    public static YXJBluetoothManager getInstance(){
        if (null==manager){
            synchronized (YXJBluetoothManager.class){
                if (null==manager){
                    manager = new YXJBluetoothManager();
                }
            }
        }
        return manager;
    }


    /**
     *
     * 获取已经配对的蓝牙设备
     *
     *
     * @return
     */
    public Set<BluetoothDevice> getBondedDevices(){
        /*获得一组代表所有配对设备的BluetoothDevice对象;*/
        Set<BluetoothDevice> listDevices = adapter.getBondedDevices();
        return listDevices;
    }



    public void listener(){
        if (isSupportBluetooth()){
            /*创建一个BluetoothServerSocket来监听传入的RFComm连接请求。*/
            try {
                adapter.listenUsingInsecureRfcommWithServiceRecord("", UUID.randomUUID());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }




    /**
     * 是否支持蓝牙
     *
     * @return
     */
    public boolean isSupportBluetooth(){
        return adapter!=null;
    }


    /**
     * 蓝牙是否打开   true为打开
     * @return
     */
    public boolean isBlueEnable() {
        return isSupportBluetooth() && adapter.isEnabled();
    }




    /**
     * 打开蓝牙
     */
    public boolean openBluetooth(){
        if (!isBlueEnable()){
            boolean b = false;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ECLAIR) {
                b = adapter.enable();
            }
            LogUtil.v("openBluetooth="+b);
            return b ;
        }
        return false ;
    }




    /**
     * 关闭蓝牙
     */
    public boolean closeBluetooth(){
        if (isBlueEnable()){
            boolean b = false;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ECLAIR) {

                if (isDiscovering()){
                    cancelDiscovery() ;
                }

                b = adapter.disable();
            }
            LogUtil.v("closeBluetooth="+b);
            return b ;
        }
        return false;
    }


    /**
     * 启动发现扫描
     */
    public boolean startDiscovery(){
        if (!isBlueEnable()){
            LogUtil.v("startDiscovery this is not open");
            return false ;
        }

        if (isDiscovering()){
            LogUtil.v("startDiscovery this is isDiscovering");
            adapter.cancelDiscovery();
        }

        /*启动蓝牙发现*/
        return adapter.startDiscovery();
    }





    /**
     * 取消扫描
     *
     * @return
     */
    public boolean cancelDiscovery(){
        if (isBlueEnable()&&isDiscovering()){
            return adapter.cancelDiscovery() ;
        }
        return false ;
    }




    /**
     * 是否正在扫描
     * @return
     */
    public boolean isDiscovering(){
        return isSupportBluetooth() && adapter.isDiscovering();
    }


    /**
     * 创建配对
     *
     * @param device
     */
    public boolean createBond(BluetoothDevice device){
        if (device.getBondState()==BluetoothDevice.BOND_NONE){
            Class<? extends BluetoothDevice> cls = device.getClass();
            try {
                Method method = cls.getMethod("createBond");
                Boolean returnValue = (Boolean) method.invoke(device);
                return returnValue.booleanValue();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        return false ;
    }





    /**
     * 解除配对
     *
     * @param device
     */
    public boolean removeBond(BluetoothDevice device){
        Class<? extends BluetoothDevice> cls = device.getClass();
        try {
            Method method = cls.getMethod("removeBond");
            Boolean returnValue = (boolean) method.invoke(device);
            return returnValue.booleanValue();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return false ;
    }


    // 取消配对
    @SuppressWarnings("unchecked")
    public boolean cancelBondProcess(Class btClass, BluetoothDevice device)  {
        Method createBondMethod = null;
        try {
            createBondMethod = btClass.getMethod("cancelBondProcess");
            Boolean returnValue = (Boolean) createBondMethod.invoke(device);
            return returnValue.booleanValue();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return false ;
    }






    /**
     * 取消用户输入
     *
     * @param btClass
     * @param device
     * @return
     * @throws Exception
     */
    public boolean cancelPairingUserInput(Class btClass, BluetoothDevice device)
            throws Exception
    {
        Method createBondMethod = btClass.getMethod("cancelPairingUserInput");
        // cancelBondProcess()
        Boolean returnValue = (Boolean) createBondMethod.invoke(device);
        Log.d("returnValue", "cancelPairingUserInput is success " + returnValue.booleanValue());
        return returnValue.booleanValue();
    }





    /**
     * 确认配对
     *
     * @param receiver
     * @param device
     */
    public boolean bondConfirmation(BroadcastReceiver receiver ,  BluetoothDevice device,String Pin){
        try {
            /**
             * 1.确认配对
             */
            Method setPairingConfirmation = device.getClass()
                    .getDeclaredMethod("setPairingConfirmation",boolean.class);
            setPairingConfirmation.invoke(device,true);

            /**
             * 2.终止有序广播
             */
            LogUtil.v("isOrderedBroadcast:"+receiver.isOrderedBroadcast()+"," + "isInitialStickyBroadcast:"+receiver.isInitialStickyBroadcast());
            //如果没有将广播终止，则会出现一个一闪而过的配对框。
            receiver.abortBroadcast();

            /**
             * 3.调用setPin方法进行配对...
             *
             *  设置匹配密钥
             */
            Method removeBondMethod = device.getClass()
                    .getDeclaredMethod("setPin", new Class[]{byte[].class});
            Boolean returnValue = (Boolean) removeBondMethod.invoke(device, new Object[]
                    {Pin.getBytes()});

            return returnValue.booleanValue() ;

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return false ;
    }




    /**
     * 获取远端的BluetoothDevice
     *
     * mac地址
     */
    public BluetoothDevice getRemoteDevice(String address){
        return adapter.getRemoteDevice(address) ;
    }




    /**
     * 注册广播
     *
     * @param context
     */
    public void register(Context context){
        scanBluetoothReceiver = new ScanBluetoothReceiver();
        scanBluetoothReceiver.setScanBluetoothListener(scanBluetoothListener);

        IntentFilter intentFilter = new IntentFilter();
        /*开始扫描可用蓝牙设备
         * android.bluetooth.adapter.action.DISCOVERY_STARTED*/
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        /*完成扫描可用蓝牙设备
         * android.bluetooth.adapter.action.DISCOVERY_FINISHED*/
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        /*扫描得到可用蓝牙设备
         * android.bluetooth.device.action.FOUND*/
        intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
        /*蓝牙配对状态变化
         * android.bluetooth.device.action.BOND_STATE_CHANGED*/
        intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        /*请求配对
         * android.bluetooth.device.action.PAIRING_REQUEST*/
        intentFilter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
        /*蓝牙配对状态进行监听
         * android.bluetooth.adapter.action.SCAN_MODE_CHANGED*/
        intentFilter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
        /*android.bluetooth.adapter.action.STATE_CHANGED*/
        intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);

        context.registerReceiver(scanBluetoothReceiver,intentFilter);
    }




    /**
     * 注销蓝牙广播
     * @param context
     */
    public  void unregister(Context context){
        if (scanBluetoothReceiver!=null){
            context.unregisterReceiver(scanBluetoothReceiver);
            scanBluetoothReceiver = null ;
        }
    }
}
